{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:01.351764Z",
     "start_time": "2025-02-04T13:59:56.696046Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:12:39.456213Z",
     "iopub.status.busy": "2025-02-04T14:12:39.455732Z",
     "iopub.status.idle": "2025-02-04T14:12:45.921239Z",
     "shell.execute_reply": "2025-02-04T14:12:45.920458Z",
     "shell.execute_reply.started": "2025-02-04T14:12:39.456164Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=10, micro=14, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 1.26.4\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.0\n",
      "torch 2.5.1+cu124\n",
      "cuda:0\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n",
    "\n",
    "seed = 42\n",
    "torch.manual_seed(seed)\n",
    "torch.cuda.manual_seed_all(seed)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 准备数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:08.502050Z",
     "start_time": "2025-02-04T14:00:01.352758Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:13:37.653314Z",
     "iopub.status.busy": "2025-02-04T14:13:37.652684Z",
     "iopub.status.idle": "2025-02-04T14:13:47.055166Z",
     "shell.execute_reply": "2025-02-04T14:13:47.054283Z",
     "shell.execute_reply.started": "2025-02-04T14:13:37.653262Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2025-02-04 22:13:38.973016: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
      "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n",
      "E0000 00:00:1738678419.141543     354 cuda_dnn.cc:8310] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
      "E0000 00:00:1738678419.190439     354 cuda_blas.cc:1418] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n",
      "2025-02-04 22:13:39.630201: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
      "To enable the following instructions: AVX2 AVX512F FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n"
     ]
    }
   ],
   "source": [
    "from tensorflow import keras\n",
    "#用karas有的数据集imdb，电影分类,分电影是积极的，还是消极的\n",
    "imdb = keras.datasets.imdb\n",
    "#载入数据使用下面两个参数\n",
    "vocab_size = 10000  #词典大小，仅保留训练数据中前10000个最经常出现的单词，低频单词被舍弃\n",
    "index_from = 3  #0,1,2,3空出来做别的事\n",
    "#前一万个词出现词频最高的会保留下来进行处理，后面的作为特殊字符处理，\n",
    "# 小于3的id都是特殊字符，下面代码有写\n",
    "# 需要注意的一点是取出来的词表还是从1开始的，需要做处理\n",
    "(train_data, train_labels), (test_data, test_labels) = imdb.load_data(\n",
    "    num_words = vocab_size, index_from = index_from)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:08.506717Z",
     "start_time": "2025-02-04T14:00:08.503174Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:13:47.057779Z",
     "iopub.status.busy": "2025-02-04T14:13:47.057165Z",
     "iopub.status.idle": "2025-02-04T14:13:47.062187Z",
     "shell.execute_reply": "2025-02-04T14:13:47.061499Z",
     "shell.execute_reply.started": "2025-02-04T14:13:47.057748Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "train 25000 (25000,)\n",
      "test 25000 (25000,)\n"
     ]
    }
   ],
   "source": [
    "\n",
    "print(\"train\", len(train_data), train_labels.shape)  #25000个样本，每个样本是一段话，每个单词用一个数字表示\n",
    "print(\"test\", len(test_data), test_labels.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:08.561117Z",
     "start_time": "2025-02-04T14:00:08.507224Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:13:47.063455Z",
     "iopub.status.busy": "2025-02-04T14:13:47.063136Z",
     "iopub.status.idle": "2025-02-04T14:13:47.139958Z",
     "shell.execute_reply": "2025-02-04T14:13:47.139202Z",
     "shell.execute_reply.started": "2025-02-04T14:13:47.063429Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "88584\n",
      "<class 'dict'>\n"
     ]
    }
   ],
   "source": [
    "#载入词表，看下词表长度，词表就像英语字典\n",
    "word_index = imdb.get_word_index()\n",
    "print(len(word_index))\n",
    "print(type(word_index))\n",
    "#词表虽然有8万多，但是我们只载入了最高频的1万词！！！！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构造 word2idx 和 idx2word"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:08.589725Z",
     "start_time": "2025-02-04T14:00:08.562112Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:13:48.720873Z",
     "iopub.status.busy": "2025-02-04T14:13:48.720354Z",
     "iopub.status.idle": "2025-02-04T14:13:48.774354Z",
     "shell.execute_reply": "2025-02-04T14:13:48.773581Z",
     "shell.execute_reply.started": "2025-02-04T14:13:48.720836Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "word2idx = {word: idx + 3 for word, idx in word_index.items()}\n",
    "word2idx.update({\n",
    "    \"[PAD]\": 0,     # 填充 token\n",
    "    \"[BOS]\": 1,     # begin of sentence\n",
    "    \"[UNK]\": 2,     # 未知 token\n",
    "    \"[EOS]\": 3,     # end of sentence\n",
    "})\n",
    "\n",
    "idx2word = {idx: word for word, idx in word2idx.items()}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:09.308730Z",
     "start_time": "2025-02-04T14:00:08.590717Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:13:50.482013Z",
     "iopub.status.busy": "2025-02-04T14:13:50.481504Z",
     "iopub.status.idle": "2025-02-04T14:13:51.870057Z",
     "shell.execute_reply": "2025-02-04T14:13:51.868942Z",
     "shell.execute_reply.started": "2025-02-04T14:13:50.481978Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAigAAAGdCAYAAAA44ojeAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAO+RJREFUeJzt3Xl4FFW+//FPb4mJZjGBbGPYlUUCAmqIC8IlCnFFcAYUHVAGRAMjoIjxqqDee8Oo4zKKOI4Kziji6GVxcMSHHZeAgCAgiIAoqAkwMiQskvRyfn94qZ8t6UCgU90N79fz1OPpqtPV3zq0qW+fU3XKYYwxAgAAiCLOSAcAAADwSyQoAAAg6pCgAACAqEOCAgAAog4JCgAAiDokKAAAIOqQoAAAgKhDggIAAKKOO9IBHI9AIKDvv/9eSUlJcjgckQ4HAAAcA2OM9u3bp5ycHDmddfeRxGSC8v333ys3NzfSYQAAgOOwY8cOnXXWWXXWickEJSkpSdJPB5icnBzhaAAAwLGoqqpSbm6udR6vS0wmKIeHdZKTk0lQYojf79eyZcskSV27dpXL5YpwRACASDiWyzNiMkFBbPL7/Zo/f74k6YILLiBBAQCERIIC2zidTnXs2NEqAwAQCgkKbON2u9WnT59IhwEAiAH1SlBKS0s1Y8YMffHFF0pISNBFF12kP/zhD2rdurVV59ChQ7r77rs1ffp0VVdXq1evXnr++eeVmZlp1dm+fbvuuOMOLVq0SGeccYYGDRqk0tJSud3kSwBwMjDGyOfzye/3RzoU2MjlcsntdodlCpB6ZQRLlixRcXGxLrjgAvl8Pt1///264oortGHDBp1++umSpNGjR+vdd9/VW2+9pZSUFI0YMUJ9+/bVRx99JOmn6xCuuuoqZWVl6eOPP1Z5ebl++9vfyuPx6H/+539O+IAAAJFVU1Oj8vJyHTx4MNKhIAISExOVnZ2tuLi4E9qPwxhjjvfNu3fvVkZGhpYsWaJu3bqpsrJSjRs31rRp03TDDTdIkr744gu1bdtWZWVl6tq1q9577z1dffXV+v77761elRdeeEHjxo3T7t27j+mAqqqqlJKSosrKSu7iiSE1NTV68sknJUljxow54S8vgOgTCAS0efNmuVwuNW7cWHFxcUyoeYowxqimpka7d++W3+/X2WeffcT1hvU5f5/QmEplZaUkKS0tTZK0atUqeb1eFRYWWnXatGmjJk2aWAlKWVmZ8vLygoZ8evXqpTvuuEOff/65OnXqdMTnVFdXq7q6OugAEZt+/u8I4ORTU1OjQCCg3NxcJSYmRjoc2CwhIUEej0fffPONampqdNpppx33vo47QQkEAho1apQuvvhitW/fXpJUUVGhuLg4paamBtXNzMxURUWFVefnycnh7Ye31aa0tFQPP/zw8YaKKOHxeDRixAirDODkxZ16p65w/dsf916Ki4u1fv16TZ8+PSyB1KWkpESVlZXWsmPHjgb/TISfw+FQenq60tPT6fIFANTpuBKUESNGaM6cOVq0aFHQXPpZWVmqqanR3r17g+rv3LlTWVlZVp2dO3cesf3wttrEx8dbs8YyeywA4GTncDg0a9asSIchSZowYYLOO+882z+3XgmKMUYjRozQzJkztXDhQjVv3jxoe5cuXeTxeLRgwQJr3aZNm7R9+3YVFBRIkgoKCrRu3Trt2rXLqjNv3jwlJyerXbt2J3IsiHJ+v1+ffPKJPvnkE249BIAoFE2JUb2uQSkuLta0adM0e/ZsJSUlWdeMpKSkKCEhQSkpKRoyZIjGjBmjtLQ0JScna+TIkSooKFDXrl0lSVdccYXatWunW265RY899pgqKir0wAMPqLi4WPHx8eE/QkQNv9+v9957T5J03nnnMdU9ACCkevWgTJ48WZWVlerevbuys7Ot5c0337TqPPXUU7r66qvVr18/devWTVlZWZoxY4a13eVyac6cOXK5XCooKNDNN9+s3/72t3rkkUfCd1SISk6nU+3atVO7du24gA5A1OnevbtGjhypUaNG6cwzz1RmZqb+8pe/6MCBA7r11luVlJSkVq1aWT+0pJ9+eA0ZMkTNmzdXQkKCWrdurWeeecbafujQIZ177rkaNmyYtW7r1q1KSkrSK6+8csyx7dixQ7/5zW+UmpqqtLQ0XXfddfr666+t7YMHD1afPn30xBNPKDs7W+np6SouLpbX67XqlJeX66qrrlJCQoKaN2+uadOmqVmzZnr66aclSc2aNZMkXX/99XI4HNbrw/72t7+pWbNmSklJ0YABA7Rv375jjv+4mBhUWVlpJJnKyspIhwIA+Jkff/zRbNiwwfz4449HbKuurjbV1dUmEAhY63w+n6murjZerzesdY/HZZddZpKSksyjjz5qvvzyS/Poo48a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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 选择 max_length\n",
    "length_collect = {}\n",
    "for text in train_data:\n",
    "    length = len(text)\n",
    "    length_collect[length] = length_collect.get(length, 0) + 1\n",
    "    \n",
    "MAX_LENGTH = 500\n",
    "plt.bar(length_collect.keys(), length_collect.values())\n",
    "plt.axvline(MAX_LENGTH, label=\"max length\", c=\"gray\", ls=\":\")\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Tokenizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:09.332365Z",
     "start_time": "2025-02-04T14:00:09.309725Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:13:54.348453Z",
     "iopub.status.busy": "2025-02-04T14:13:54.347865Z",
     "iopub.status.idle": "2025-02-04T14:13:54.387619Z",
     "shell.execute_reply": "2025-02-04T14:13:54.386912Z",
     "shell.execute_reply.started": "2025-02-04T14:13:54.348421Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "raw text\n",
      "['hello', 'world']\n",
      "['tokenize', 'text', 'datas', 'with', 'batch']\n",
      "['this', 'is', 'a', 'test']\n",
      "indices\n",
      "tensor([   0,    0,    0,    1, 4825,  182,    3])\n",
      "tensor([    1,     2,  3004,     2,    19, 19233,     3])\n",
      "tensor([   0,    1,   14,    9,    6, 2181,    3])\n",
      "decode text\n",
      "[PAD] [PAD] [PAD] [BOS] hello world [EOS]\n",
      "[BOS] [UNK] text [UNK] with batch [EOS]\n",
      "[PAD] [BOS] this is a test [EOS]\n"
     ]
    }
   ],
   "source": [
    "class Tokenizer:\n",
    "    def __init__(self, word2idx, idx2word, max_length=500, pad_idx=0, bos_idx=1, eos_idx=3, unk_idx=2):\n",
    "        self.word2idx = word2idx\n",
    "        self.idx2word = idx2word\n",
    "        self.max_length = max_length\n",
    "        self.pad_idx = pad_idx\n",
    "        self.bos_idx = bos_idx\n",
    "        self.eos_idx = eos_idx\n",
    "        self.unk_idx = unk_idx\n",
    "    \n",
    "    def encode(self, text_list, padding_first=False):\n",
    "        \"\"\"如果padding_first == True，则padding加载前面，否则加载后面\"\"\"\n",
    "        max_length = min(self.max_length, 2 + max([len(text) for text in text_list]))\n",
    "        indices_list = []\n",
    "        for text in text_list:\n",
    "            indices = [self.bos_idx] + [self.word2idx.get(word, self.unk_idx) for word in text[:max_length-2]] + [self.eos_idx]\n",
    "            if padding_first:\n",
    "                indices = [self.pad_idx] * (max_length - len(indices)) + indices\n",
    "            else:\n",
    "                indices = indices + [self.pad_idx] * (max_length - len(indices))\n",
    "            indices_list.append(indices)\n",
    "        return torch.tensor(indices_list)\n",
    "    \n",
    "    \n",
    "    def decode(self, indices_list, remove_bos=True, remove_eos=True, remove_pad=True, split=False):\n",
    "        text_list = []\n",
    "        for indices in indices_list:\n",
    "            text = []\n",
    "            for index in indices:\n",
    "                word = self.idx2word.get(index, \"[UNK]\")\n",
    "                if remove_bos and word == \"[BOS]\":\n",
    "                    continue\n",
    "                if remove_eos and word == \"[EOS]\":\n",
    "                    break\n",
    "                if remove_pad and word == \"[PAD]\":\n",
    "                    break\n",
    "                text.append(word)\n",
    "            text_list.append(\" \".join(text) if not split else text)\n",
    "        return text_list\n",
    "    \n",
    "\n",
    "tokenizer = Tokenizer(word2idx=word2idx, idx2word=idx2word)\n",
    "raw_text = [\"hello world\".split(), \"tokenize text datas with batch\".split(), \"this is a test\".split()]\n",
    "indices = tokenizer.encode(raw_text, padding_first=True)\n",
    "decode_text = tokenizer.decode(indices.tolist(), remove_bos=False, remove_eos=False, remove_pad=False)\n",
    "print(\"raw text\")\n",
    "for raw in raw_text:\n",
    "    print(raw)\n",
    "print(\"indices\")\n",
    "for index in indices:\n",
    "    print(index)\n",
    "print(\"decode text\")\n",
    "for decode in decode_text:\n",
    "    print(decode)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:09.336585Z",
     "start_time": "2025-02-04T14:00:09.332365Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:13:56.476315Z",
     "iopub.status.busy": "2025-02-04T14:13:56.475832Z",
     "iopub.status.idle": "2025-02-04T14:13:56.482748Z",
     "shell.execute_reply": "2025-02-04T14:13:56.481781Z",
     "shell.execute_reply.started": "2025-02-04T14:13:56.476279Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[\"[BOS] this film was just brilliant casting location scenery story direction everyone's really suited the part they played and you could just imagine being there robert [UNK] is an amazing actor and now the same being director [UNK] father came from the same scottish island as myself so i loved the fact there was a real connection with this film the witty remarks throughout the film were great it was just brilliant so much that i bought the film as soon as it was released for [UNK] and would recommend it to everyone to watch and the fly fishing was amazing really cried at the end it was so sad and you know what they say if you cry at a film it must have been good and this definitely was also [UNK] to the two little boy's that played the [UNK] of norman and paul they were just brilliant children are often left out of the [UNK] list i think because the stars that play them all grown up are such a big profile for the whole film but these children are amazing and should be praised for what they have done don't you think the whole story was so lovely because it was true and was someone's life after all that was shared with us all\",\n",
       " \"[BOS] big hair big boobs bad music and a giant safety pin these are the words to best describe this terrible movie i love cheesy horror movies and i've seen hundreds but this had got to be on of the worst ever made the plot is paper thin and ridiculous the acting is an abomination the script is completely laughable the best is the end showdown with the cop and how he worked out who the killer is it's just so damn terribly written the clothes are sickening and funny in equal [UNK] the hair is big lots of boobs [UNK] men wear those cut [UNK] shirts that show off their [UNK] sickening that men actually wore them and the music is just [UNK] trash that plays over and over again in almost every scene there is trashy music boobs and [UNK] taking away bodies and the gym still doesn't close for [UNK] all joking aside this is a truly bad film whose only charm is to look back on the disaster that was the 80's and have a good old laugh at how bad everything was back then\"]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 看看训练集的数据\n",
    "\n",
    "tokenizer.decode(train_data[:2], remove_bos=False, remove_eos=False, remove_pad=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据集与 DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:10.858100Z",
     "start_time": "2025-02-04T14:00:09.336585Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:13:59.452170Z",
     "iopub.status.busy": "2025-02-04T14:13:59.451683Z",
     "iopub.status.idle": "2025-02-04T14:14:02.821539Z",
     "shell.execute_reply": "2025-02-04T14:14:02.820720Z",
     "shell.execute_reply.started": "2025-02-04T14:13:59.452137Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from torch.utils.data import Dataset, DataLoader\n",
    "\n",
    "class IMDBDataset(Dataset):\n",
    "    def __init__(self, data, labels, remain_length=True):\n",
    "        if remain_length:\n",
    "            self.data = tokenizer.decode(data, remove_bos=False, remove_eos=False, remove_pad=False)\n",
    "        else:\n",
    "            # 缩减一下数据\n",
    "            self.data = tokenizer.decode(data)\n",
    "        self.labels = labels\n",
    "    \n",
    "    def __getitem__(self, index):\n",
    "        text = self.data[index]\n",
    "        label = self.labels[index]\n",
    "        return text, label\n",
    "    \n",
    "    def __len__(self):\n",
    "        return len(self.data)\n",
    "    \n",
    "    \n",
    "def collate_fct(batch):\n",
    "    text_list = [item[0].split() for item in batch]\n",
    "    label_list = [item[1] for item in batch]\n",
    "    # 这里使用 padding first\n",
    "    text_list = tokenizer.encode(text_list, padding_first=True).to(dtype=torch.int)\n",
    "    return text_list, torch.tensor(label_list).reshape(-1, 1).to(dtype=torch.float)\n",
    "\n",
    "\n",
    "# 用RNN，缩短序列长度\n",
    "train_ds = IMDBDataset(train_data, train_labels, remain_length=False)\n",
    "test_ds = IMDBDataset(test_data, test_labels, remain_length=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:10.862360Z",
     "start_time": "2025-02-04T14:00:10.858726Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:14:05.815625Z",
     "iopub.status.busy": "2025-02-04T14:14:05.815006Z",
     "iopub.status.idle": "2025-02-04T14:14:05.820579Z",
     "shell.execute_reply": "2025-02-04T14:14:05.819736Z",
     "shell.execute_reply.started": "2025-02-04T14:14:05.815580Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "batch_size = 128\n",
    "train_dl = DataLoader(train_ds, batch_size=batch_size, shuffle=True, collate_fn=collate_fct)\n",
    "test_dl = DataLoader(test_ds, batch_size=batch_size, shuffle=False, collate_fn=collate_fct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:00:10.900231Z",
     "start_time": "2025-02-04T14:00:10.862360Z"
    },
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2025-02-04T14:14:07.268692Z",
     "iopub.status.busy": "2025-02-04T14:14:07.268168Z",
     "iopub.status.idle": "2025-02-04T14:14:07.316784Z",
     "shell.execute_reply": "2025-02-04T14:14:07.316048Z",
     "shell.execute_reply.started": "2025-02-04T14:14:07.268655Z"
    },
    "jupyter": {
     "outputs_hidden": false
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([128, 500]) torch.Size([128, 1])\n"
     ]
    }
   ],
   "source": [
    "for text, label in train_dl: #检查样本是否存在问题\n",
    "    print(text.shape, label.shape)\n",
    "    break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:06:14.558437Z",
     "start_time": "2025-02-04T14:06:14.550818Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:14:11.176392Z",
     "iopub.status.busy": "2025-02-04T14:14:11.175882Z",
     "iopub.status.idle": "2025-02-04T14:14:11.189853Z",
     "shell.execute_reply": "2025-02-04T14:14:11.189133Z",
     "shell.execute_reply.started": "2025-02-04T14:14:11.176358Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================== 一层单向 LSTM ===================================\n",
      "            embeding.weight             paramerters num: 160000\n",
      "           lstm.weight_ih_l0            paramerters num: 4096\n",
      "           lstm.weight_hh_l0            paramerters num: 16384\n",
      "            lstm.bias_ih_l0             paramerters num: 256\n",
      "            lstm.bias_hh_l0             paramerters num: 256\n",
      "              layer.weight              paramerters num: 4096\n",
      "               layer.bias               paramerters num: 64\n",
      "               fc.weight                paramerters num: 64\n",
      "                fc.bias                 paramerters num: 1\n"
     ]
    }
   ],
   "source": [
    "class LSTM(nn.Module):\n",
    "    def __init__(self, embedding_dim=16, hidden_dim=64, vocab_size=vocab_size, num_layers=1, bidirectional=False):\n",
    "        super(LSTM, self).__init__()\n",
    "        self.embeding = nn.Embedding(vocab_size, embedding_dim)\n",
    "        self.lstm = nn.LSTM(embedding_dim, hidden_dim, num_layers=num_layers, batch_first=True, bidirectional=bidirectional)\n",
    "        self.layer = nn.Linear(hidden_dim * (2 if bidirectional else 1), hidden_dim)\n",
    "        self.fc = nn.Linear(hidden_dim, 1)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # [bs, seq length]\n",
    "        x = self.embeding(x)\n",
    "        # [bs, seq length, embedding_dim] -> shape [bs, seq length，hidden_dim]\n",
    "        seq_output, (hidden, cell) = self.lstm(x) # [bs,500,64](500个时间步，每个时间步64维),([1,bs,64],[1,bsd,64])\n",
    "        # print(f'seq_output.shape: {seq_output.shape}')\n",
    "        # print(f'hidden: {hidden.shape}')\n",
    "        # print(f'cell: {cell.shape}')\n",
    "        # print(seq_output[:, -1, :].squeeze()==hidden.squeeze())  # hidden及seq_output最后一个时间步的输出\n",
    "        # print(seq_output[:, -1, :].squeeze()==cell.squeeze())\n",
    "        x = seq_output[:, -1, :]\n",
    "        # 取最后一个时间步的输出 (这也是为什么要设置padding_first=True的原因)\n",
    "        x = self.layer(x)\n",
    "        x = self.fc(x)\n",
    "        return x\n",
    "    \n",
    "sample_inputs = torch.randint(0, vocab_size, (2, 128))\n",
    "    \n",
    "print(\"{:=^80}\".format(\" 一层单向 LSTM \"))       \n",
    "for key, value in LSTM().named_parameters():\n",
    "    print(f\"{key:^40}paramerters num: {np.prod(value.shape)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:06:17.366435Z",
     "start_time": "2025-02-04T14:06:17.332846Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "seq_output.shape: torch.Size([128, 500, 64])\n",
      "hidden: torch.Size([1, 128, 64])\n",
      "cell: torch.Size([1, 128, 64])\n",
      "tensor([[True, True, True,  ..., True, True, True],\n",
      "        [True, True, True,  ..., True, True, True],\n",
      "        [True, True, True,  ..., True, True, True],\n",
      "        ...,\n",
      "        [True, True, True,  ..., True, True, True],\n",
      "        [True, True, True,  ..., True, True, True],\n",
      "        [True, True, True,  ..., True, True, True]])\n",
      "tensor([[False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        ...,\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False],\n",
      "        [False, False, False,  ..., False, False, False]])\n",
      "torch.Size([128, 1])\n"
     ]
    }
   ],
   "source": [
    "model = LSTM()\n",
    "#随机一个（128,500）的输入\n",
    "sample_inputs = torch.randint(0, vocab_size, (128, 500))\n",
    "sample_outputs = model(sample_inputs)\n",
    "print(sample_outputs.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-05-02T08:36:09.545313600Z",
     "start_time": "2024-05-02T08:36:09.506335700Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4096"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4 * 16 * 64 #lstm.weight_ih_l0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:08:43.207028Z",
     "start_time": "2025-02-04T14:08:43.200867Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================== 一层双向 LSTM ===================================\n",
      "            embeding.weight             paramerters num: 160000\n",
      "           lstm.weight_ih_l0            paramerters num: 4096\n",
      "           lstm.weight_hh_l0            paramerters num: 16384\n",
      "            lstm.bias_ih_l0             paramerters num: 256\n",
      "            lstm.bias_hh_l0             paramerters num: 256\n",
      "       lstm.weight_ih_l0_reverse        paramerters num: 4096\n",
      "       lstm.weight_hh_l0_reverse        paramerters num: 16384\n",
      "        lstm.bias_ih_l0_reverse         paramerters num: 256\n",
      "        lstm.bias_hh_l0_reverse         paramerters num: 256\n",
      "              layer.weight              paramerters num: 8192\n",
      "               layer.bias               paramerters num: 64\n",
      "               fc.weight                paramerters num: 64\n",
      "                fc.bias                 paramerters num: 1\n"
     ]
    }
   ],
   "source": [
    "print(\"{:=^80}\".format(\" 一层双向 LSTM \"))\n",
    "for key, value in LSTM(bidirectional=True).named_parameters():\n",
    "    print(f\"{key:^40}paramerters num: {np.prod(value.shape)}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8192"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "128*64"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:08:45.270122Z",
     "start_time": "2025-02-04T14:08:45.264065Z"
    },
    "collapsed": false,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "================================== 两层单向 LSTM ===================================\n",
      "            embeding.weight             paramerters num: 160000\n",
      "           lstm.weight_ih_l0            paramerters num: 4096\n",
      "           lstm.weight_hh_l0            paramerters num: 16384\n",
      "            lstm.bias_ih_l0             paramerters num: 256\n",
      "            lstm.bias_hh_l0             paramerters num: 256\n",
      "           lstm.weight_ih_l1            paramerters num: 16384\n",
      "           lstm.weight_hh_l1            paramerters num: 16384\n",
      "            lstm.bias_ih_l1             paramerters num: 256\n",
      "            lstm.bias_hh_l1             paramerters num: 256\n",
      "              layer.weight              paramerters num: 4096\n",
      "               layer.bias               paramerters num: 64\n",
      "               fc.weight                paramerters num: 64\n",
      "                fc.bias                 paramerters num: 1\n"
     ]
    }
   ],
   "source": [
    "print(\"{:=^80}\".format(\" 两层单向 LSTM \"))\n",
    "for key, value in LSTM(num_layers=2).named_parameters():\n",
    "    print(f\"{key:^40}paramerters num: {np.prod(value.shape)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-04T14:10:58.536377Z",
     "start_time": "2025-02-04T14:10:58.532697Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16384"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "4*64*64  # 下一层输入是上一层输出，由16变64"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-04T14:17:54.787270Z",
     "iopub.status.busy": "2025-02-04T14:17:54.786670Z",
     "iopub.status.idle": "2025-02-04T14:17:54.791100Z",
     "shell.execute_reply": "2025-02-04T14:17:54.790351Z",
     "shell.execute_reply.started": "2025-02-04T14:17:54.787240Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def count_parameters(model):\n",
    "    return sum(p.numel() for p in model.parameters() if p.requires_grad)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-04T14:17:54.792280Z",
     "iopub.status.busy": "2025-02-04T14:17:54.791945Z",
     "iopub.status.idle": "2025-02-04T14:17:54.807565Z",
     "shell.execute_reply": "2025-02-04T14:17:54.806730Z",
     "shell.execute_reply.started": "2025-02-04T14:17:54.792253Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "185217\n",
      "210305\n",
      "218497\n",
      "309633\n"
     ]
    }
   ],
   "source": [
    "print(count_parameters(LSTM()))\n",
    "print(count_parameters(LSTM(bidirectional=True)))\n",
    "print(count_parameters(LSTM(num_layers=2)))\n",
    "print(count_parameters(LSTM(num_layers=2,bidirectional=True)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-07-30T02:57:22.790960200Z",
     "start_time": "2024-07-30T02:57:22.446263Z"
    },
    "execution": {
     "iopub.execute_input": "2025-02-04T14:14:18.131927Z",
     "iopub.status.busy": "2025-02-04T14:14:18.131386Z",
     "iopub.status.idle": "2025-02-04T14:14:18.745074Z",
     "shell.execute_reply": "2025-02-04T14:14:18.744179Z",
     "shell.execute_reply.started": "2025-02-04T14:14:18.131892Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    pred_list = []\n",
    "    label_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        # 二分类\n",
    "        preds = logits > 0\n",
    "        pred_list.extend(preds.cpu().numpy().tolist())\n",
    "        label_list.extend(labels.cpu().numpy().tolist())\n",
    "        \n",
    "    acc = accuracy_score(label_list, pred_list)\n",
    "    return np.mean(loss_list), acc\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "source": [
    "### TensorBoard 可视化\n",
    "\n",
    "\n",
    "训练过程中可以使用如下命令启动tensorboard服务。\n",
    "\n",
    "```shell\n",
    "tensorboard \\\n",
    "    --logdir=runs \\     # log 存放路径\n",
    "    --host 0.0.0.0 \\    # ip\n",
    "    --port 8848         # 端口\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-04T14:14:23.419546Z",
     "iopub.status.busy": "2025-02-04T14:14:23.418773Z",
     "iopub.status.idle": "2025-02-04T14:14:23.579781Z",
     "shell.execute_reply": "2025-02-04T14:14:23.579032Z",
     "shell.execute_reply.started": "2025-02-04T14:14:23.419508Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from torch.utils.tensorboard import SummaryWriter\n",
    "\n",
    "\n",
    "class TensorBoardCallback:\n",
    "    def __init__(self, log_dir, flush_secs=10):\n",
    "        \"\"\"\n",
    "        Args:\n",
    "            log_dir (str): dir to write log.\n",
    "            flush_secs (int, optional): write to dsk each flush_secs seconds. Defaults to 10.\n",
    "        \"\"\"\n",
    "        self.writer = SummaryWriter(log_dir=log_dir, flush_secs=flush_secs)\n",
    "\n",
    "    def draw_model(self, model, input_shape):\n",
    "        self.writer.add_graph(model, input_to_model=torch.randn(input_shape))\n",
    "        \n",
    "    def add_loss_scalars(self, step, loss, val_loss):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/loss\", \n",
    "            tag_scalar_dict={\"loss\": loss, \"val_loss\": val_loss},\n",
    "            global_step=step,\n",
    "            )\n",
    "        \n",
    "    def add_acc_scalars(self, step, acc, val_acc):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/accuracy\",\n",
    "            tag_scalar_dict={\"accuracy\": acc, \"val_accuracy\": val_acc},\n",
    "            global_step=step,\n",
    "        )\n",
    "        \n",
    "    def add_lr_scalars(self, step, learning_rate):\n",
    "        self.writer.add_scalars(\n",
    "            main_tag=\"training/learning_rate\",\n",
    "            tag_scalar_dict={\"learning_rate\": learning_rate},\n",
    "            global_step=step,\n",
    "            \n",
    "        )\n",
    "    \n",
    "    def __call__(self, step, **kwargs):\n",
    "        # add loss\n",
    "        loss = kwargs.pop(\"loss\", None)\n",
    "        val_loss = kwargs.pop(\"val_loss\", None)\n",
    "        if loss is not None and val_loss is not None:\n",
    "            self.add_loss_scalars(step, loss, val_loss)\n",
    "        # add acc\n",
    "        acc = kwargs.pop(\"acc\", None)\n",
    "        val_acc = kwargs.pop(\"val_acc\", None)\n",
    "        if acc is not None and val_acc is not None:\n",
    "            self.add_acc_scalars(step, acc, val_acc)\n",
    "        # add lr\n",
    "        learning_rate = kwargs.pop(\"lr\", None)\n",
    "        if learning_rate is not None:\n",
    "            self.add_lr_scalars(step, learning_rate)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "source": [
    "### Save Best\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-04T14:14:27.514942Z",
     "iopub.status.busy": "2025-02-04T14:14:27.514402Z",
     "iopub.status.idle": "2025-02-04T14:14:27.521781Z",
     "shell.execute_reply": "2025-02-04T14:14:27.521023Z",
     "shell.execute_reply.started": "2025-02-04T14:14:27.514907Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "class SaveCheckpointsCallback:\n",
    "    def __init__(self, save_dir, save_step=5000, save_best_only=True):\n",
    "        \"\"\"\n",
    "        Save checkpoints each save_epoch epoch. \n",
    "        We save checkpoint by epoch in this implementation.\n",
    "        Usually, training scripts with pytorch evaluating model and save checkpoint by step.\n",
    "\n",
    "        Args:\n",
    "            save_dir (str): dir to save checkpoint\n",
    "            save_epoch (int, optional): the frequency to save checkpoint. Defaults to 1.\n",
    "            save_best_only (bool, optional): If True, only save the best model or save each model at every epoch.\n",
    "        \"\"\"\n",
    "        self.save_dir = save_dir\n",
    "        self.save_step = save_step\n",
    "        self.save_best_only = save_best_only\n",
    "        self.best_metrics = -1\n",
    "        \n",
    "        # mkdir\n",
    "        if not os.path.exists(self.save_dir):\n",
    "            os.mkdir(self.save_dir)\n",
    "        \n",
    "    def __call__(self, step, state_dict, metric=None):\n",
    "        if step % self.save_step > 0:\n",
    "            return\n",
    "        \n",
    "        if self.save_best_only:\n",
    "            assert metric is not None\n",
    "            if metric >= self.best_metrics:\n",
    "                # save checkpoints\n",
    "                torch.save(state_dict, os.path.join(self.save_dir, \"best.ckpt\"))\n",
    "                # update best metrics\n",
    "                self.best_metrics = metric\n",
    "        else:\n",
    "            torch.save(state_dict, os.path.join(self.save_dir, f\"{step}.ckpt\"))\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "source": [
    "### Early Stop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-04T14:14:31.376461Z",
     "iopub.status.busy": "2025-02-04T14:14:31.375991Z",
     "iopub.status.idle": "2025-02-04T14:14:31.382492Z",
     "shell.execute_reply": "2025-02-04T14:14:31.381596Z",
     "shell.execute_reply.started": "2025-02-04T14:14:31.376428Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "jp-MarkdownHeadingCollapsed": true,
    "tags": []
   },
   "source": [
    "### training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-04T14:14:45.796153Z",
     "iopub.status.busy": "2025-02-04T14:14:45.795407Z",
     "iopub.status.idle": "2025-02-04T14:17:54.785406Z",
     "shell.execute_reply": "2025-02-04T14:17:54.784660Z",
     "shell.execute_reply.started": "2025-02-04T14:14:45.796099Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 3920/3920 [03:06<00:00, 20.99it/s, epoch=19]\n"
     ]
    }
   ],
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    tensorboard_callback=None,\n",
    "    save_ckpt_callback=None,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas)\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    "                preds = logits > 0\n",
    "            \n",
    "                acc = accuracy_score(labels.cpu().numpy(), preds.cpu().numpy())    \n",
    "                loss = loss.cpu().item()\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"acc\": acc, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss, val_acc = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"acc\": val_acc, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "                    \n",
    "                    # 1. 使用 tensorboard 可视化\n",
    "                    if tensorboard_callback is not None:\n",
    "                        tensorboard_callback(\n",
    "                            global_step, \n",
    "                            loss=loss, val_loss=val_loss,\n",
    "                            acc=acc, val_acc=val_acc,\n",
    "                            lr=optimizer.param_groups[0][\"lr\"],\n",
    "                            )\n",
    "                \n",
    "                    # 2. 保存模型权重 save model checkpoint\n",
    "                    if save_ckpt_callback is not None:\n",
    "                        save_ckpt_callback(global_step, model.state_dict(), metric=val_acc)\n",
    "\n",
    "                    # 3. 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(val_acc)\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 20\n",
    "\n",
    "model = LSTM()\n",
    "\n",
    "# 1. 定义损失函数 采用交叉熵损失 (但是二分类)\n",
    "loss_fct = F.binary_cross_entropy_with_logits\n",
    "# 2. 定义优化器 采用 adam\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
    "\n",
    "# 1. tensorboard 可视化\n",
    "if not os.path.exists(\"runs\"):\n",
    "    os.mkdir(\"runs\")\n",
    "tensorboard_callback = TensorBoardCallback(\"runs/imdb-lstm\")\n",
    "# tensorboard_callback.draw_model(model, [1, MAX_LENGTH])\n",
    "# 2. save best\n",
    "if not os.path.exists(\"checkpoints\"):\n",
    "    os.makedirs(\"checkpoints\")\n",
    "save_ckpt_callback = SaveCheckpointsCallback(\"checkpoints/imdb-lstm\", save_step=len(train_dl), save_best_only=True)\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_dl, \n",
    "    test_dl, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    tensorboard_callback=tensorboard_callback,\n",
    "    save_ckpt_callback=save_ckpt_callback,\n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_dl)\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-04T14:19:32.229830Z",
     "iopub.status.busy": "2025-02-04T14:19:32.229315Z",
     "iopub.status.idle": "2025-02-04T14:19:32.497755Z",
     "shell.execute_reply": "2025-02-04T14:19:32.496959Z",
     "shell.execute_reply.started": "2025-02-04T14:19:32.229792Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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27dvBwIubtdcc02w/S233MKWLVu49957Wb9+Pa+++ioff/wxd999d4X10eoc0X/DFf0X7zlSnc8Pn8/Hn//8Z9q2bUtaWhqdO3fmhRdeCGv3xhtvBM+Zpk2bMm7cuOBnR48e5eabbyYnJ4fU1FROOOEEvvnmm7j2LwhC8vhl0wFGPzeHv32yqqq7AohlKC7W783jg8U7ALhrRKcq7o0gVD+KPD66PfRDlez7t0dHk54S36XshRdeYOPGjZxwwgk8+uijAKxduxaA++67j2eeeYZ27dpRr149duzYwZgxY3j88cdxOp28/fbbnHPOOWzYsIFWrVpF3McjjzzCU089xdNPP81LL73EVVddxbZt26hfv35Cx7Vs2TIuvfRSHn74YS677DLmz5/PbbfdRoMGDRg7dixLly7ljjvu4J133mHo0KEcPnyYX375BYA9e/ZwxRVX8NRTT3HBBReQl5fHL7/8kpBwrEksXbqUU089Nfhej+259tpreeutt9izZ09QGAG0bduWb7/9lrvvvpsXXniBFi1a8J///CepabVDqQnnSHU+P/x+Py1atOCTTz6hQYMGzJ8/n5tuuomcnBzOOOMMAP71r38xfvx4nnzySc4880yOHTvGvHnzguufeeaZ5OXl8e6779K+fXt+++23Wp8lThCqI8eKPGzYl0e9jOrhSihiKA5cXkl7Kgi1gTp16pCSkkJ6ejpNmjQBYP369QA8+uijjBw5Mti2fv369OrVK/j+scce44svvuDrr782PW0OZezYsVxxxRUAPPHEE7z44ossXrw4OGGLl8mTJ3P66afz4IMPAtCpUyd+++03nn76acaOHcv27dvJyMjg7LPPJisri9atW9OnTx8gIIa8Xi8XXnghrVu3BqBHjx4J7b8mccopp0QVem+99ZblOitWrKjAXtU8qvP54XA4TNn82rZty4IFC/jkk0+C6/7jH//gr3/9qylhw4ABAwCYOXMmixcvZt26dXTqFHio2a5du9iDIghC0vH5A9drm1o9kseIGIoD41fl92uo1eTLE4TqQprDxm+PVtxT9VD8fj95uXlkZWeR5kjOk93+/fub3ufn5/Pwww/z7bffBsVFUVGRycJgRc+ePYOvMzIyyM7OZv/+/Qn3Z926dZx33nmmZcOGDeP555/H5/MxcuRIWrduTbt27TjjjDM444wzgu5HvXr1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",
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    fig_num = len(train_df.columns)\n",
    "    fig, axs = plt.subplots(1, fig_num, figsize=(5 * fig_num, 5))\n",
    "    for idx, item in enumerate(train_df.columns):    \n",
    "        axs[idx].plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        axs[idx].plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        axs[idx].grid()\n",
    "        axs[idx].legend()\n",
    "        # axs[idx].set_xticks(range(0, train_df.index[-1], 5000))\n",
    "        # axs[idx].set_xticklabels(map(lambda x: f\"{int(x/1000)}k\", range(0, train_df.index[-1], 5000)))\n",
    "        axs[idx].set_xlabel(\"step\")\n",
    "    \n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(record, sample_step=10)  #横坐标是 steps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 评估"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2025-02-04T14:19:35.227195Z",
     "iopub.status.busy": "2025-02-04T14:19:35.226690Z",
     "iopub.status.idle": "2025-02-04T14:19:39.312280Z",
     "shell.execute_reply": "2025-02-04T14:19:39.311057Z",
     "shell.execute_reply.started": "2025-02-04T14:19:35.227159Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_354/1661179837.py:4: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n",
      "  model.load_state_dict(torch.load(\"checkpoints/imdb-lstm/best.ckpt\", map_location=\"cpu\"))\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3321\n",
      "accuracy: 0.8741\n"
     ]
    }
   ],
   "source": [
    "# dataload for evaluating\n",
    "\n",
    "# load checkpoints\n",
    "model.load_state_dict(torch.load(\"checkpoints/imdb-lstm/best.ckpt\", map_location=\"cpu\"))\n",
    "\n",
    "model.eval()\n",
    "loss, acc = evaluating(model, test_dl, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\\naccuracy: {acc:.4f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
